Skip to content

BCDA-9874: Initial file_ingestion Implementation (bene-prefs)#1323

Merged
juliareynolds-nava merged 24 commits intomainfrom
bcda-9874
Mar 11, 2026
Merged

BCDA-9874: Initial file_ingestion Implementation (bene-prefs)#1323
juliareynolds-nava merged 24 commits intomainfrom
bcda-9874

Conversation

@mjburling
Copy link
Member

@mjburling mjburling commented Mar 5, 2026

🎫 Ticket

BCDA-9874

🛠 Changes

Added a new S3 bucket, lambda, and associated iam roles and policies.

ℹ️ Context

Changed the pickup bucket for the lambda that consumes bene prefs file input. Added iam and security groups for the new location.

🧪 Validation

Click to expand Plan Output
OpenTofu used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place
-/+ destroy and then create replacement
 <= read (data resources)

OpenTofu will perform the following actions:

  # aws_iam_policy.default_function will be updated in-place
  ~ resource "aws_iam_policy" "default_function" {
        id               = "arn:aws:iam::202533514245:policy/delegatedadmin/developer/bcda-prod-bene-prefs-default-function"
        name             = "bcda-prod-bene-prefs-default-function"
      ~ policy           = jsonencode(
          ~ {
              ~ Statement = [
                  ~ {
                      ~ Action   = [
                            # (7 unchanged elements hidden)
                            "logs:CreateLogGroup",
                          - "ec2:DescribeNetworkInterfaces",
                          - "ec2:DescribeAccountAttributes",
                          - "ec2:DeleteNetworkInterface",
                          - "ec2:CreateNetworkInterface",
                        ]
                        # (3 unchanged attributes hidden)
                    },
                    {
                        Action   = [
                            "kms:GenerateDataKey",
                            "kms:Encrypt",
                            "kms:Decrypt",
                        ]
                        Effect   = "Allow"
                        Resource = [
                            "arn:aws:kms:us-west-2:202533514245:key/b8998658-3910-45fe-818a-64e88d8009c1",
                            "arn:aws:kms:us-east-1:202533514245:key/37584589-3eb7-437a-9f20-b7fc0a951eb3",
                        ]
                        Sid      = "KmsEncryptDecrypt"
                    },
                ]
                # (1 unchanged attribute hidden)
            }
        )
        tags             = {}
        # (6 unchanged attributes hidden)
    }

  # aws_lambda_function.this will be updated in-place
  ~ resource "aws_lambda_function" "this" {
        id                             = "bcda-prod-bene-prefs"
      ~ last_modified                  = "2026-03-06T21:58:40.180+0000" -> (known after apply)
      ~ s3_bucket                      = "bcda-prod-bene-prefs-20260304231106069900000001" -> (known after apply)
        tags                           = {
            "code" = "https://github.com/CMSgov/bcda-app/tree/main/bcda/lambda/optout"
        }
        # (23 unchanged attributes hidden)

        # (5 unchanged blocks hidden)
    }

  # module.bucket.data.aws_iam_policy_document.ssl_only will be read during apply
  # (config refers to values not yet known)
 <= data "aws_iam_policy_document" "ssl_only" {
      + id            = (known after apply)
      + json          = (known after apply)
      + minified_json = (known after apply)

      + statement {
          + actions   = [
              + "s3:*",
            ]
          + effect    = "Deny"
          + resources = [
              + (known after apply),
              + (known after apply),
            ]
          + sid       = "AllowSSLRequestsOnly"

          + condition {
              + test     = "Bool"
              + values   = [
                  + "false",
                ]
              + variable = "aws:SecureTransport"
            }

          + principals {
              + identifiers = [
                  + "*",
                ]
              + type        = "AWS"
            }
        }
    }

  # module.bucket.data.aws_iam_policy_document.this will be read during apply
  # (config refers to values not yet known)
 <= data "aws_iam_policy_document" "this" {
      + id                      = (known after apply)
      + json                    = (known after apply)
      + minified_json           = (known after apply)
      + source_policy_documents = [
          + (known after apply),
        ]
    }

  # module.bucket.aws_s3_bucket.this must be replaced
-/+ resource "aws_s3_bucket" "this" {
      + acceleration_status         = (known after apply)
      + acl                         = (known after apply)
      ~ arn                         = "arn:aws:s3:::bcda-prod-bene-prefs-20260304231106069900000001" -> (known after apply)
      ~ bucket                      = "bcda-prod-bene-prefs-20260304231106069900000001" -> (known after apply)
      ~ bucket_domain_name          = "bcda-prod-bene-prefs-20260304231106069900000001.s3.amazonaws.com" -> (known after apply)
      ~ bucket_prefix               = "bcda-prod-bene-prefs-" -> "bcda-prod-bene-prefs-lambda-" # forces replacement
      ~ bucket_regional_domain_name = "bcda-prod-bene-prefs-20260304231106069900000001.s3.us-east-1.amazonaws.com" -> (known after apply)
      ~ hosted_zone_id              = "Z3AQBSTGFYJSTF" -> (known after apply)
      ~ id                          = "bcda-prod-bene-prefs-20260304231106069900000001" -> (known after apply)
      ~ object_lock_enabled         = false -> (known after apply)
      ~ policy                      = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = "s3:*"
                      - Condition = {
                          - Bool = {
                              - "aws:SecureTransport" = "false"
                            }
                        }
                      - Effect    = "Deny"
                      - Principal = {
                          - AWS = "*"
                        }
                      - Resource  = [
                          - "arn:aws:s3:::bcda-prod-bene-prefs-20260304231106069900000001/*",
                          - "arn:aws:s3:::bcda-prod-bene-prefs-20260304231106069900000001",
                        ]
                      - Sid       = "AllowSSLRequestsOnly"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
      ~ region                      = "us-east-1" -> (known after apply)
      ~ request_payer               = "BucketOwner" -> (known after apply)
      - tags                        = {} -> null
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)
        # (2 unchanged attributes hidden)

      ~ cors_rule {
          + acceleration_status         = (known after apply)
          + acl                         = (known after apply)
          + arn                         = (known after apply)
          + bucket                      = (known after apply)
          + bucket_domain_name          = (known after apply)
          + bucket_prefix               = (known after apply)
          + bucket_regional_domain_name = (known after apply)
          + force_destroy               = (known after apply)
          + hosted_zone_id              = (known after apply)
          + id                          = (known after apply)
          + object_lock_enabled         = (known after apply)
          + policy                      = (known after apply)
          + region                      = (known after apply)
          + request_payer               = (known after apply)
          + tags                        = (known after apply)
          + tags_all                    = (known after apply)
          + website_domain              = (known after apply)
          + website_endpoint            = (known after apply)
        } -> (known after apply)

      ~ grant {
          + acceleration_status         = (known after apply)
          + acl                         = (known after apply)
          + arn                         = (known after apply)
          + bucket                      = (known after apply)
          + bucket_domain_name          = (known after apply)
          + bucket_prefix               = (known after apply)
          + bucket_regional_domain_name = (known after apply)
          + force_destroy               = (known after apply)
          + hosted_zone_id              = (known after apply)
          + id                          = (known after apply)
          + object_lock_enabled         = (known after apply)
          + policy                      = (known after apply)
          + region                      = (known after apply)
          + request_payer               = (known after apply)
          + tags                        = (known after apply)
          + tags_all                    = (known after apply)
          + website_domain              = (known after apply)
          + website_endpoint            = (known after apply)
        } -> (known after apply)

      ~ lifecycle_rule {
          + acceleration_status         = (known after apply)
          + acl                         = (known after apply)
          + arn                         = (known after apply)
          + bucket                      = (known after apply)
          + bucket_domain_name          = (known after apply)
          + bucket_prefix               = (known after apply)
          + bucket_regional_domain_name = (known after apply)
          + force_destroy               = (known after apply)
          + hosted_zone_id              = (known after apply)
          + id                          = (known after apply)
          + object_lock_enabled         = (known after apply)
          + policy                      = (known after apply)
          + region                      = (known after apply)
          + request_payer               = (known after apply)
          + tags                        = (known after apply)
          + tags_all                    = (known after apply)
          + website_domain              = (known after apply)
          + website_endpoint            = (known after apply)
        } -> (known after apply)

      ~ logging {
          + acceleration_status         = (known after apply)
          + acl                         = (known after apply)
          + arn                         = (known after apply)
          + bucket                      = (known after apply)
          + bucket_domain_name          = (known after apply)
          + bucket_prefix               = (known after apply)
          + bucket_regional_domain_name = (known after apply)
          + force_destroy               = (known after apply)
          + hosted_zone_id              = (known after apply)
          + id                          = (known after apply)
          + object_lock_enabled         = (known after apply)
          + policy                      = (known after apply)
          + region                      = (known after apply)
          + request_payer               = (known after apply)
          + tags                        = (known after apply)
          + tags_all                    = (known after apply)
          + website_domain              = (known after apply)
          + website_endpoint            = (known after apply)
        } -> (known after apply)

      ~ object_lock_configuration {
          + acceleration_status         = (known after apply)
          + acl                         = (known after apply)
          + arn                         = (known after apply)
          + bucket                      = (known after apply)
          + bucket_domain_name          = (known after apply)
          + bucket_prefix               = (known after apply)
          + bucket_regional_domain_name = (known after apply)
          + force_destroy               = (known after apply)
          + hosted_zone_id              = (known after apply)
          + id                          = (known after apply)
          + object_lock_enabled         = (known after apply)
          + policy                      = (known after apply)
          + region                      = (known after apply)
          + request_payer               = (known after apply)
          + tags                        = (known after apply)
          + tags_all                    = (known after apply)
          + website_domain              = (known after apply)
          + website_endpoint            = (known after apply)
        } -> (known after apply)

      ~ replication_configuration {
          + acceleration_status         = (known after apply)
          + acl                         = (known after apply)
          + arn                         = (known after apply)
          + bucket                      = (known after apply)
          + bucket_domain_name          = (known after apply)
          + bucket_prefix               = (known after apply)
          + bucket_regional_domain_name = (known after apply)
          + force_destroy               = (known after apply)
          + hosted_zone_id              = (known after apply)
          + id                          = (known after apply)
          + object_lock_enabled         = (known after apply)
          + policy                      = (known after apply)
          + region                      = (known after apply)
          + request_payer               = (known after apply)
          + tags                        = (known after apply)
          + tags_all                    = (known after apply)
          + website_domain              = (known after apply)
          + website_endpoint            = (known after apply)
        } -> (known after apply)

      ~ server_side_encryption_configuration {
          + acceleration_status         = (known after apply)
          + acl                         = (known after apply)
          + arn                         = (known after apply)
          + bucket                      = (known after apply)
          + bucket_domain_name          = (known after apply)
          + bucket_prefix               = (known after apply)
          + bucket_regional_domain_name = (known after apply)
          + force_destroy               = (known after apply)
          + hosted_zone_id              = (known after apply)
          + id                          = (known after apply)
          + object_lock_enabled         = (known after apply)
          + policy                      = (known after apply)
          + region                      = (known after apply)
          + request_payer               = (known after apply)
          + tags                        = (known after apply)
          + tags_all                    = (known after apply)
          + website_domain              = (known after apply)
          + website_endpoint            = (known after apply)
        } -> (known after apply)

      ~ versioning {
          + acceleration_status         = (known after apply)
          + acl                         = (known after apply)
          + arn                         = (known after apply)
          + bucket                      = (known after apply)
          + bucket_domain_name          = (known after apply)
          + bucket_prefix               = (known after apply)
          + bucket_regional_domain_name = (known after apply)
          + force_destroy               = (known after apply)
          + hosted_zone_id              = (known after apply)
          + id                          = (known after apply)
          + object_lock_enabled         = (known after apply)
          + policy                      = (known after apply)
          + region                      = (known after apply)
          + request_payer               = (known after apply)
          + tags                        = (known after apply)
          + tags_all                    = (known after apply)
          + website_domain              = (known after apply)
          + website_endpoint            = (known after apply)
        } -> (known after apply)

      ~ website {
          + acceleration_status         = (known after apply)
          + acl                         = (known after apply)
          + arn                         = (known after apply)
          + bucket                      = (known after apply)
          + bucket_domain_name          = (known after apply)
          + bucket_prefix               = (known after apply)
          + bucket_regional_domain_name = (known after apply)
          + force_destroy               = (known after apply)
          + hosted_zone_id              = (known after apply)
          + id                          = (known after apply)
          + object_lock_enabled         = (known after apply)
          + policy                      = (known after apply)
          + region                      = (known after apply)
          + request_payer               = (known after apply)
          + tags                        = (known after apply)
          + tags_all                    = (known after apply)
          + website_domain              = (known after apply)
          + website_endpoint            = (known after apply)
        } -> (known after apply)
    }

  # module.bucket.aws_s3_bucket_lifecycle_configuration.this must be replaced
-/+ resource "aws_s3_bucket_lifecycle_configuration" "this" {
      ~ bucket                                 = "bcda-prod-bene-prefs-20260304231106069900000001" # forces replacement -> (known after apply) # forces replacement
      + expected_bucket_owner                  = (known after apply)
      ~ id                                     = "bcda-prod-bene-prefs-20260304231106069900000001" -> (known after apply)
        # (1 unchanged attribute hidden)

        # (2 unchanged blocks hidden)
    }

  # module.bucket.aws_s3_bucket_logging.this must be replaced
-/+ resource "aws_s3_bucket_logging" "this" {
      ~ bucket        = "bcda-prod-bene-prefs-20260304231106069900000001" # forces replacement -> (known after apply) # forces replacement
      ~ id            = "bcda-prod-bene-prefs-20260304231106069900000001" -> (known after apply)
      ~ target_prefix = "bcda-prod-bene-prefs-20260304231106069900000001/" -> (known after apply)
        # (1 unchanged attribute hidden)
    }

  # module.bucket.aws_s3_bucket_policy.this must be replaced
-/+ resource "aws_s3_bucket_policy" "this" {
      ~ bucket = "bcda-prod-bene-prefs-20260304231106069900000001" # forces replacement -> (known after apply) # forces replacement
      ~ id     = "bcda-prod-bene-prefs-20260304231106069900000001" -> (known after apply)
      ~ policy = jsonencode(
            {
              - Statement = [
                  - {
                      - Action    = "s3:*"
                      - Condition = {
                          - Bool = {
                              - "aws:SecureTransport" = "false"
                            }
                        }
                      - Effect    = "Deny"
                      - Principal = {
                          - AWS = "*"
                        }
                      - Resource  = [
                          - "arn:aws:s3:::bcda-prod-bene-prefs-20260304231106069900000001/*",
                          - "arn:aws:s3:::bcda-prod-bene-prefs-20260304231106069900000001",
                        ]
                      - Sid       = "AllowSSLRequestsOnly"
                    },
                ]
              - Version   = "2012-10-17"
            }
        ) -> (known after apply)
    }

  # module.bucket.aws_s3_bucket_server_side_encryption_configuration.this must be replaced
-/+ resource "aws_s3_bucket_server_side_encryption_configuration" "this" {
      ~ bucket = "bcda-prod-bene-prefs-20260304231106069900000001" # forces replacement -> (known after apply) # forces replacement
      ~ id     = "bcda-prod-bene-prefs-20260304231106069900000001" -> (known after apply)

        # (1 unchanged block hidden)
    }

  # module.bucket.aws_s3_bucket_versioning.this must be replaced
-/+ resource "aws_s3_bucket_versioning" "this" {
      ~ bucket = "bcda-prod-bene-prefs-20260304231106069900000001" # forces replacement -> (known after apply) # forces replacement
      ~ id     = "bcda-prod-bene-prefs-20260304231106069900000001" -> (known after apply)

      ~ versioning_configuration {
          + mfa_delete = (known after apply)
            # (1 unchanged attribute hidden)
        }
    }

  # module.bucket.aws_ssm_parameter.bucket[0] will be updated in-place
  ~ resource "aws_ssm_parameter" "bucket" {
        id             = "/bcda/prod/bene-prefs/nonsensitive/bucket_name"
      + insecure_value = (known after apply)
        name           = "/bcda/prod/bene-prefs/nonsensitive/bucket_name"
        tags           = {}
      ~ value          = (sensitive value)
      ~ version        = 1 -> (known after apply)
        # (5 unchanged attributes hidden)
    }

Plan: 6 to add, 3 to change, 6 to destroy.

@juliareynolds-nava juliareynolds-nava changed the title BCDA-9874: Initial Bene Prefs Implementation BCDA-9874: Initial file_ingestion Implementation (bene-prefs) Mar 5, 2026
@juliareynolds-nava juliareynolds-nava marked this pull request as ready for review March 6, 2026 19:11
@juliareynolds-nava juliareynolds-nava requested a review from a team as a code owner March 6, 2026 19:11
@juliareynolds-nava juliareynolds-nava marked this pull request as draft March 6, 2026 19:58
@juliareynolds-nava juliareynolds-nava marked this pull request as ready for review March 9, 2026 14:32
@juliareynolds-nava juliareynolds-nava requested a review from a team March 10, 2026 17:26
@juliareynolds-nava juliareynolds-nava merged commit 6e218a4 into main Mar 11, 2026
7 checks passed
@juliareynolds-nava juliareynolds-nava deleted the bcda-9874 branch March 11, 2026 17:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants